package com.surveyingandmapping.ionospheretec.service.impl;

import com.surveyingandmapping.ionospheretec.model.ObservationData;
import jxl.write.Label;
import jxl.write.WritableSheet;
import jxl.write.WriteException;
import org.apache.commons.lang3.StringUtils;
import org.springframework.util.Assert;
import org.springframework.util.comparator.InstanceComparator;


import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Stack;

/**
 * Created by Carly rea jepsen on 2016/3/23.
 */
public class DataProcessing {

    /**
     * 获取变量排序
     * @param s
     * @return
     */
    public static Stack<String> sortObservationData(String[] s)
    {
        Stack<String> type= new Stack<String>();
        for(int i=5;i<s.length;i++){
            if (s[i].equals("OBSERV")&&s[i-1].equals("OF")&&s[i-2].equals("TYPES")&&s[i-3].equals("/")&&s[i-4].equals("#")){
                for(int j=i-5;j>=0;j--){
                    if(s[j].matches("[0-9]+")!=true){
                        type.push(s[j]);
                    }else {
                        int n = Integer.parseInt(s[j]);
                        if(type.size()==n) {
                            return type;
                        }
                    }
                }
            }
        }

        return null;
    }

    /**
     * 将观测数据添加到对象中
     * @param type
     * @param observation
     * @return
     */
    public static ObservationData addObservation(Stack<String> type,String[] observation)
    {
        ObservationData observationData = new ObservationData();
        for(int i=0;!type.isEmpty();i++){
            String s = type.pop();
            if(s.equals(Constant.Observation_L1)){
                observationData.setL1(Double.parseDouble(observation[i]));
            }else if(s.equals(Constant.Observation_L2)){
                observationData.setL2(Double.parseDouble(observation[i]));
            }else if (s.equals(Constant.Observation_C1)){
                observationData.setC1(Double.parseDouble(observation[i]));
            }else if (s.equals(Constant.Observation_P1)){
                observationData.setP1(Double.parseDouble(observation[i]));
            }else if(s.equals(Constant.Observation_P2)){
                observationData.setP2(Double.parseDouble(observation[i]));
            }else if(s.equals(Constant.Observation_EL)){
                observationData.setEl(Double.parseDouble(observation[i]));
            }else if(s.equals(Constant.Observation_L0)){
                observationData.setLo(Double.parseDouble(observation[i]));
            }else if(s.equals(Constant.Observation_LA)){
                observationData.setLa(Double.parseDouble(observation[i]));
            }
        }

        return observationData;
    }

    /**
     * 获取同一历元的所有数据
     * @param str
     * @param i
     * @param type
     * @return
     */
    public static List<ObservationData> addObservationList(String[] str,int i,Stack<String> type) throws NumberFormatException
    {
        List<ObservationData> observationDataList = new ArrayList<ObservationData>();
        Assert.isTrue(i<str.length-8,"文件内容出错");
        String year = str[i];
        String month = str[i+1];
        String day = str[i+2];
        String h = str[i+3];
        String m = str[i+4];
        String[] st = StringUtils.split(str[i+5],".");
        String s = st[0];
        String[] satellite = StringUtils.split(str[i+7],Constant.SATELLITE_PARTITION);
        if(satellite.length<=1){
            System.out.println();
        }
        Assert.isTrue(satellite.length>1,"文件卫星有错");
        int number = Integer.parseInt(satellite[0]);
        Assert.isTrue(number==satellite.length-1,"文件卫星数有错");
        Assert.isTrue(i<(str.length-8+(satellite.length-1)*type.size()),"文件观测数据有缺失");
        for(int j=1;j<satellite.length;j++){
            String[] observation = new String[type.size()];
            int n=0;
            for(int k = i+(j-1)*type.size()+8;k<i+j*type.size()+8;k++){
                observation[n] = str[k];
                n++;
            }
            Stack<String> type1 = new Stack<String>();
            type1.addAll(type);
            ObservationData observationData = addObservation(type1,observation);
            observationData.setYear(year);
            observationData.setMonth(month);
            observationData.setDay(day);
            observationData.setH(h);
            observationData.setM(m);
            observationData.setS(s);
            observationData.setSatelliteNo(Integer.parseInt(satellite[j]));
            observationDataList.add(observationData);
        }

        return observationDataList;
    }

    /**
     * 读取文件中的所有数据
     * @param str
     * @param type
     * @return
     */
    public static List<ObservationData> addAllObservation(String[] str,Stack<String> type)
    {
        List<ObservationData> allObsercationData = new ArrayList<ObservationData>();
        int j = 0 ;
        for (int i=3;i<str.length-1;i++){
            if(str[i-3].equals("END")&&str[i-2].equals("OF")&&str[i-1].equals("HEADER")){
                j=i;
            }
        }
        if(j==0){
            return null;
        }
        while(j<str.length-1){
            Stack<String> type1 = new Stack<String>();
            type1.addAll(type);
            List<ObservationData> observationDataList = addObservationList(str,j,type1);
            j = j+observationDataList.size()*type.size()+8;
            allObsercationData.addAll(observationDataList);
        }

        return allObsercationData;
    }

    /**
     * Excel添加首行
     * @param sheet
     * @throws WriteException
     */
    public static void addExcelHead(WritableSheet sheet) throws WriteException
    {
        Label label1 = new Label(0,0,Constant.ObservationExcel.EPOCH_TIME);
        Label label2 = new Label(1,0,Constant.ObservationExcel.SATELLITE_NO);
        Label label3 = new Label(2,0,Constant.ObservationExcel.L1_VALUE);
        Label label4 = new Label(3,0,Constant.ObservationExcel.L2_VALUE);
        Label label5 = new Label(4,0,Constant.ObservationExcel.C1_VALUE);
        Label label6 = new Label(5,0,Constant.ObservationExcel.P1_VALUE);
        Label label7 = new Label(6,0,Constant.ObservationExcel.P2_VALUE);
        Label label8 = new Label(7,0,Constant.ObservationExcel.EL_VALUE);
        Label label9 = new Label(8,0,Constant.ObservationExcel.LA_VALUE);
        Label label10 = new Label(9,0,Constant.ObservationExcel.LO_VALUE);
        sheet.addCell(label1);
        sheet.addCell(label2);
        sheet.addCell(label3);
        sheet.addCell(label4);
        sheet.addCell(label5);
        sheet.addCell(label6);
        sheet.addCell(label7);
        sheet.addCell(label8);
        sheet.addCell(label9);
        sheet.addCell(label10);
    }

    public static void addExcelValue(WritableSheet sheet,int i,ObservationData observationData) throws WriteException,ParseException
    {
        String time = getTime(observationData);
        Label variable1 = new Label(0,i+1,time);
        jxl.write.Number variable2 = new jxl.write.Number(1,i+1,observationData.getSatelliteNo());
        jxl.write.Number variable3 = new jxl.write.Number(2,i+1,observationData.getL1());
        jxl.write.Number variable4 = new jxl.write.Number(3,i+1,observationData.getL2());
        jxl.write.Number variable5 = new jxl.write.Number(4,i+1,observationData.getC1());
        jxl.write.Number variable6 = new jxl.write.Number(5,i+1,observationData.getP1());
        jxl.write.Number variable7 = new jxl.write.Number(6,i+1,observationData.getP2());
        jxl.write.Number variable8 = new jxl.write.Number(7,i+1,observationData.getEl());
        jxl.write.Number variable9 = new jxl.write.Number(8,i+1,observationData.getLa());
        jxl.write.Number variable10 = new jxl.write.Number(9,i+1,observationData.getLo());
        sheet.addCell(variable1);
        sheet.addCell(variable2);
        sheet.addCell(variable3);
        sheet.addCell(variable4);
        sheet.addCell(variable5);
        sheet.addCell(variable6);
        sheet.addCell(variable7);
        sheet.addCell(variable8);
        sheet.addCell(variable9);
        sheet.addCell(variable10);
    }

    /**
     * 获取历元
     * @param observationData
     * @return
     */
    public static String getTime(ObservationData observationData) throws ParseException
    {
        StringBuffer sb = new StringBuffer();
        String year = observationData.getYear();
        String month = observationData.getMonth();
        String day = observationData.getDay();
        String h = observationData.getH();
        String m = observationData.getM();
        String s = observationData.getS();
        sb.append("20").append(year).append("-").append(month).append("-").append(day).append(" ").append(h).append(":").append(m).append(":").append(s);
        String time = sb.toString();
        return time;
    }

    public static ObservationDataDto transformObservationData(ObservationData observationData) throws ParseException{
        ObservationDataDto observationDataDto = new ObservationDataDto();
        observationDataDto.setSatelliteNo(observationData.getSatelliteNo());
        observationDataDto.setL1(observationData.getL1());
        observationDataDto.setL2(observationData.getL2());
        observationDataDto.setC1(observationData.getC1());
        observationDataDto.setP1(observationData.getP1());
        observationDataDto.setP2(observationData.getP2());
        observationDataDto.setEl(observationData.getEl());
        observationDataDto.setLa(observationData.getLa());
        observationDataDto.setLo(observationData.getLo());
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
        String time = getTime(observationData);
        Date epoch = sdf.parse(time);
        observationDataDto.setEpoch(epoch);

        return observationDataDto;
    }
}
